package com.ldu.exam.service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import javax.transaction.Transactional;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.ldu.exam.assistant.BeanAssistant;
import com.ldu.exam.dao.MenuRepository;
import com.ldu.exam.dao.RoleRepository;
import com.ldu.exam.model.AccountModel;
import com.ldu.exam.model.ClaModel;
import com.ldu.exam.model.MenuModel;
import com.ldu.exam.model.ResourceModel;
import com.ldu.exam.model.RoleModel;

@Service
public class RoleService 
{
	@Autowired private RoleRepository repository ;
	
	public Page<RoleModel> findAll( Pageable page)
	{
		return this.repository.findAll( page) ;
	}
	
	public RoleModel find( String id)
	{
		return this.repository.findById(id).orElse(null) ;
	}
	
	public void delete( String id )
	{
		 this.repository.deleteById(id);
	}
	
	public RoleModel save (RoleModel model)
	{
		return this.repository.save( model);
	}

	public RoleModel relateAccount( String id, AccountModel account)
	{
		RoleModel role = this.find(id) ;
		role.getAccounts().add(  account);
		
		return this.repository.save( role);
	}
	
//	@Transactional
//	public Object putResources( String id, Set<ResourceModel> resources)
//	{
//		this.repository.removeRelResources( id);
//		
//		RoleModel role = this.find(id) ;
//		role.getResources().addAll( resources);
//		
//		return this.repository.save( role);
//	}
	
	@Autowired private MenuRepository menuRepository ;
	@Transactional
	public Object putMenus( String id,  Set<MenuModel> menus)
	{
		this.repository.removeRelMenus( id);
		
		RoleModel role = this.find(id) ;
		
		//add parent menus 
		List<String> ids = menus.stream().map( x->x.getId()).collect( Collectors.toList()) ;
		
		Set<MenuModel> wholeMenus = menus.stream()
										 .map( x->  this.menuRepository.findById( x.getId()).get())
										 .collect(Collectors.toSet()) 
		;
		
		Set<MenuModel> parentMenus = wholeMenus .stream()
												.filter( x-> ! StringUtils.isEmpty( x.getParentId()))
												.filter( x -> ! ids.contains( x.getParentId()))
												.map( y -> y.getParentId())
												.distinct()
												.map( z -> this.menuRepository.findById(z).get())
												.collect( Collectors.toSet()) 
		;
		
		role.getMenus().addAll( menus) ;
		role.getMenus().addAll( parentMenus) ;
		
		return this.repository.save( role);
	}
	
	@Transactional
	public RoleModel update( String id, RoleModel model) 
	{
		model.setId(null);
		
		RoleModel origin = this.find( id) ;
		
		String [] nullPropertyNames = BeanAssistant.getNullPropertyNames( model,"creationDate","updateDate") ;
		
		BeanUtils.copyProperties( model,  origin, nullPropertyNames);
		
		return this.repository.save( origin);
	}
	
	public Page<RoleModel> findByName( String name, Pageable page) 
	{
		return this.repository.findByNameContaining(name, page);
	}

	@Autowired private AccountService accountService ;
	public List<RoleModel> findAllByUserId( String userId) 
	{
		if( userId.equals("1b6fa0a6075211e98eb2f2801f1b9fd1"))
			return this.repository.findAll() ;
		
		AccountModel account = this.accountService.find( userId) ;
		Set<RoleModel> roles = account.getRoles() ;
		
		if( null == roles || 1 > roles.size())
			return null ;
		
		List<RoleModel> result = roles.stream()
									.filter ( BeanAssistant.distinctByKey( RoleModel::getId))
									.filter ( x-> ! StringUtils.isEmpty( x.getId()))
									.collect( Collectors.toList()) ;
		return result ;
	}
	public Object isExit(String name)
	{
		List<RoleModel> list = this.repository.findByName(name);
		if(list.size()>0) {
			return false;
		}else {
			return true;
		}
	}
	public List<RoleModel> findByNoPage()
	{
		return this.repository.findAll();
	}
	
	public Object isStudent(String roleId)
	{
		RoleModel model  = this.repository.findById(roleId).orElse(null);
		if(model.getName().equalsIgnoreCase("学生"))
		{
			return "student";
		}else if (model.getName().equalsIgnoreCase("教师"))
		{
			return "teacher";
		}else {
			return false;
		}
	}
}